#!/usr/bin/env python
#coding: iso-8859-1

"""Documentation for bullet.py

Contains the bullet class which 
follow enemies and destroys them

project -- Rez: The Clone
author -- Edwood Grant
organization -- Binhex Tw. 
version -- 1.00
since -- 7/07/2007 13:33:42
"""

#Panda specific imports for this module
from pandac.PandaModules import * 
#To handle events
from direct.showbase import DirectObject

#Standard imports
from random import random

#To handle actors
from direct.actor import Actor

#To handle intervals
from direct.interval.IntervalGlobal import *

#T

#User imports
import globals




class Bullet(DirectObject.DirectObject):
    def __init__(self, actorEnd, pos):
        """Constructor
        
        We are not doing anything special here, only when we decide to init  
        right here we are only creating some variables     
        """

        #The actor we want to reach to
        self.actorGoal = actorEnd
        self.pos = pos
        self.posi = 0
        
        try:
            self.snd = loader.loadSfx(globals.SHOOTSOUNDS[self.posi])
        except:
            sndToLoad = self.posi % len(globals.SHOOTSOUNDS)
            self.snd = loader.loadSfx(globals.SHOOTSOUNDS[sndToLoad])
        self.snd.play()

        #Given a position (the first bullet, the sedond, the third, etc...
        #We initialize the bullet function with init function
        # Defines and loads the model...
        self.node = render.attachNewNode("Bullet")
        globals.MISSIL_LIGHT_POSITION.reparentTo(self.node)
        globals.BULLET = 1
        self.node.setPos(0, 0, 0)
        self.model = loader.loadModelCopy(globals.BULLETEGG) 
        self.model.setScale(4.0)
        self.model.setH(90)
        #Enables transparency to the model
        #Make it visible
        self.duration = 2.5
        self.model.setPos(self.node.getPos())
        self.model.reparentTo(self.node)
        #self.model.endPos = (Point3(globals.PlayerPosition.getX()+100,globals.PlayerPosition.getY(),globals.PlayerPosition.getZ()))
        self.parallel = ProjectileInterval(self.node,startPos = self.pos,endPos = self.actorGoal-Point3(0,0,-5),duration = self.duration,gravityMult=-2)
        self.parallel.start()

        #Initializes the collision handler event
        #Enabling 'into-%in' collision types
        self.colNode = CollisionNode('Bullet') 
        #Seting "from" bitmask to 0
        self.colNode.setFromCollideMask(BitMask32.bit(1))
        self.colNode.setIntoCollideMask(BitMask32.bit(1))

        self.colNode.addSolid(CollisionSphere(0, 0, 0, 2))
        self.colNodePath = self.model.attachNewNode(self.colNode)
        #Adding the collider to the main traverser, and assign its event handler     
        base.cTrav.addCollider(self.colNodePath, globals.PhysicsBox)
        #We add an accept to chekeck every time our collision into-%in occurs
        self.colNodePath.show()

        globals.WORLD.accept('into-enemyTestCol',self._enemyCol)
        
        #Update Task
        self.updateTask = taskMgr.add(self._update, 'Bullet-Update') 
        self.updateTask.last = 0


    def _enemyMidiCol(self, collEntry):
        obj = collEntry.getIntoNodePath().getParent()
        enemy_name = obj.getNetTag('enemy')
        print "enemyCol:",  obj, enemy_name


        
    def _enemyCol(self, collEntry):
        """EnemyCol event
        
        Trigger every time this bullet collide with something inside enemyCol
        """
        #We obtain the tag fo the object and attempt to find it
        
        obj = collEntry.getIntoNodePath().getParent()
        enemy_name = obj.getNetTag('enemy')
        print "enemyCol:",  obj, enemy_name
        if enemy_name != None:
            obj = globals.ENEMIES[enemy_name]

        #If it was found, then kill the enemy
        if obj != None and hasattr(obj, 'die'):
            #print obj
            obj.die()
            if self.parallel.isPlaying():
                self.parallel.finish()

        #self.parallel.finish()

    def _update(self, task):
        if not self.parallel.isPlaying():
            self.node.removeNode()
            del self
            #print "delete"
            globals.BULLET = 0
            return task.done

        return task.cont



class BulletEnemy():
    def __init__(self, actorEnd, pos):
        """Constructor

        We are not doing anything special here, only when we decide to init
        right here we are only creating some variables
        """

        #The actor we want to reach to
        self.actorGoal = actorEnd
        self.pos = pos
        self.posi = 0


        #Given a position (the first bullet, the sedond, the third, etc...
        #We initialize the bullet function with init function
        # Defines and loads the model...
        self.node = render.attachNewNode("Bullet")
        #globals.MISSIL_LIGHT_POSITION.reparentTo(self.node)

        self.node.setPos(0, 0, 0)
        self.model = loader.loadModelCopy(globals.BULLETEGG)
        self.model.setScale(2.0)
        self.model.setH(90)
        #Enables transparency to the model
        #Make it visible
        self.duration = 1.6
        self.model.setPos(self.node.getPos())
        self.model.reparentTo(self.node)
        #self.model.endPos = (Point3(globals.PlayerPosition.getX()+100,globals.PlayerPosition.getY(),globals.PlayerPosition.getZ()))
        self.parallel = ProjectileInterval(self.node,startPos = self.pos,endPos = self.actorGoal,duration = self.duration)
        self.parallel.start()

        #Initializes the collision handler event
        #Enabling 'into-%in' collision types
        self.colNode = CollisionNode('enemyShoot')
        #Seting "from" bitmask to 0
        self.colNode.setFromCollideMask(BitMask32.bit(3))
        self.colNode.setIntoCollideMask(BitMask32.bit(2))

        self.colNode.addSolid(CollisionSphere(0, 0, 0, 1))
        self.colNodePath = self.model.attachNewNode(self.colNode)
        #Adding the collider to the main traverser, and assign its event handler
        base.cTrav.addCollider(self.colNodePath, globals.PhysicsBox)
        #We add an accept to chekeck every time our collision into-%in occurs

        #Update Task
        self.updateTask = taskMgr.add(self._update, 'Bullet-Update')
        self.updateTask.last = 0


    def _update(self, task):
        if not self.parallel.isPlaying():
            self.node.removeNode()
            del self
            return task.done

        return task.cont
